/*
 *  
    Copyright (C) 2008  Nathaniel Waisbrot

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package termint.brains;

import java.util.Vector;

import termint.gui.vt.VT320;
import termint.gui.vt.VTChangeEvent;
import termint.gui.vt.VTChangeListener;

/**
 * Message watcher listens for new Nethack messages to come in on the VT, then alerts the TextBuffer.
 * @author Nathaniel Waisbrot
 *
 */
public class MessageWatcher implements VTChangeListener {
	private static final int firstRow = 0;
	private static final String moreMessage = "--More-";
	protected Vector<MessageListener> buffers;
	
	public MessageWatcher(VT320 vt) {
		this.buffers = new Vector<MessageListener>();
		vt.addVTChangeListener(this);
	}
	
	public void addMessageListener(MessageListener listener) {
		if (!buffers.contains(listener)) {
			buffers.add(listener);
		}
	}
	
	public void removeMessageListener(MessageListener listener) {
		buffers.remove(listener);
	}
	
	public void notifyMessage(String message) {
		for (MessageListener l : buffers) {
			l.newText(message);
		}
	}
	
	public void notifyQuestion(String question) {
		for (MessageListener l : buffers) {
			l.newQuestion(question);
		}
	}

	public void VTChanged(VTChangeEvent event) {
		// must include a change in line 1 to be a message
		if (!event.getChanges()[firstRow]) 
			return;

		VT320 vt = event.getSource();
		String currentRow = vtLineToString(vt.getRow(vt.getCursorRow()));
		if (currentRow.contains(moreMessage)) {
			// it is safe to add everything up to the --More--
			StringBuilder s = new StringBuilder();
			for (int i = 0; i < vt.getCursorRow(); i++) {
				s.append(vt.getRow(i));
			}
			s.append(vtLineToString(vt.getRow(vt.getCursorRow()), vt.getCursorColumn() - moreMessage.length()));
			s.append("\n");
			notifyMessage(s.toString());
		} else if ((vt.getCursorRow() != 0) && (vt.getCursorRow() != 1)) {
			// if the cursor isn't in the first two rows, then we can be sure the user isn't typing.
			// if there was no "--MORE--", then it's all in the first row
			String s = vtLineToString(vt.getRow(0));
			if (s.length() > 0 && s.charAt(0) != '\0') {
				notifyMessage(s + "\n");
			}
		} else {
			// user appears to be typing, or we're in the middle of receiving data.
			String s = vtLineToString(vt.getRow(0));
			if (vt.getCursorRow() == 1)
				s += vtLineToString(vt.getRow(1));
			if (s.matches(".*\\[[a-z]+\\].*\\([a-z]+\\).*"))
				notifyQuestion(s);
		}
	}
	
	private String vtLineToString(char[] line) {
		return vtLineToString(line, line.length);
	}
	private String vtLineToString(char[] line, int maxLen) {
		int lastChar = 0;
		// locate the right-most character in the line
		for (int i = 0; i < maxLen; i++) {
			if (line[i] != '\0')
				lastChar = i;
		}
		// take everything up to that as a string
		String s = String.copyValueOf(line, 0, lastChar+1);
		// replace nulls with spaces
		String result = s.replace('\0', ' ');
		return result;
	}
}
